Optimization::Optimization (std::string contestD, std::string benchmarkN, int pollingT
                            , updFunctionPtr updater)							
{
	cout << "Optimization Class is constructed..." << endl ;
	this->contestDir = contestD ;
	this->benchmarkName = benchmarkN ;
	this->pollingTime = pollingT ;
	this->updaterFunction = updater ;
}


int Optimization::getPollingTime () const
{
	return this->pollingTime ;
}

void Optimization::setPollingTime(int value)
{
	this->pollingTime = value ;
}

updFunctionPtr Optimization::getUpdaterFunction()
{
	return this->updaterFunction ;
}

void Optimization::setUpdaterFunction(updFunctionPtr func)
{
	this->updaterFunction = func ;
}

void Optimization::updateCellType (CircuitGraph& graphIn)
{
	this->updaterFunction(graphIn) ;
}


void Optimization::buildSizerFile(CircuitGraph& graphIn, bool isFinal)
{
	boost::graph_traits<CircuitGraph>::vertex_iterator vi, vi_end ;
	string sizerFileName = this->contestDir + "/" + this->benchmarkName + "/" + 
                this->benchmarkName ;
								
	if (!isFinal)
		sizerFileName = sizerFileName + ".int" ;
		
	sizerFileName = sizerFileName + ".sizes" ;
								
	std::ofstream outFile(sizerFileName.c_str());
	
  	if (!outFile) {
   		cout << "Sizes: Could not write sizes into " << sizerFileName << endl;
   	 	exit(1);
  	}
	
	for (tie(vi, vi_end) = boost::vertices(graphIn) ; vi != vi_end ; ++vi)
	{
		if (graphIn[(*vi)].gateType == Combinational || graphIn[(*vi)].gateType == Sequential)
		{
			//cout << graphIn[(*vi)].instanceName << " " << graphIn[(*vi)].cellName << endl ;
			outFile << graphIn[(*vi)].instanceName << " " << graphIn[(*vi)].cellName << endl ;
		}
	}
	outFile.close();
}

std::vector<std::pair<std::string, std::string> > Optimization::readSizes (const std::string &filename)
{
	std::vector<std::pair<std::string, std::string> > sizes ;
	
	std::ifstream infile(filename.c_str()) ;
	
	if (!infile) {
                cout << "-E-: readSizes: Could not read sizes from '" << filename << "'" << endl;
                exit(1);
 	}
 	
 	string inst, size ;
 	
 	while (!infile.eof()) {
 		infile >> inst ;
 		if (infile.eof()) break ;
 		infile >> size ;
 		if (infile.eof()) break ;
 		sizes.push_back(make_pair(inst, size)) ;
 	}
 	
 	infile.close() ;
 	return sizes ;
	
}

int Optimization::callTimer()
{
	string benchmarkFile = this->contestDir + "/" + this->benchmarkName
                + "/" + this->benchmarkName + ".int.sizes";
	cout << "Running timing analysis on " << benchmarkFile << endl ;
	TimerInterface::Status s = TimerInterface::runTimingAnalysisBlocking( this->readSizes(benchmarkFile)
                                                                              , this->contestDir, this->benchmarkName
                                                                              , this->pollingTime) ;
											
	cout << "Timing analysis finished with status: " << s << endl ;
	
   	if (TimerInterface::TIMER_FINISHED_SUCCESS != s) {
                cout << "-E-: Something went wrong, exiting. Check pt.log in ISPD_CONTEST_ROOT directory" << endl;
                exit(1);
	}
	
	return 0 ;
	
}
